#include <stdio.h>
#include <stdlib.h>

#define MAX_INFO_LEN 2048

int isValidChar( int c );

int decrypt( char* info, int len ); 

int main( int argc, char const *argv[] ) {
    FILE *fp; 
    fp =fopen("/home/data/cppproj/0809ZJU007A/net/crypt/cipher1.txt", "r");   
    /* your add must be different from mine, so you may not able to use my progress to work out this*/
    if (!fp) { /* checking of error */
        printf("err when opening\n");
        return EXIT_FAILURE;
    }
    char info[MAX_INFO_LEN] = {0};/* cipher1.txt */
    int index=0; /* length */
    int c;
    char str[3]; /* store up to 3 numbers */
    int i = 0;
    /* input */
    while ( (c = getc(fp)) != EOF ) {
        if (c == ',') { /* end */
            str[i] = 0;
            c = atoi(str); /* make c ASCII */
            info[index++] = c; /* store */
            i = 0; 
        } else { /* input */
            str[i++] = c;
        }
        if ( i >= 3 ) {
            printf("err when input\n");
            return EXIT_FAILURE;
        }
    }
/* in case there is more than one answer */
    if (i>0) {
        str[i] = 0;
        int c = atoi(str);
        info[index++] = c;
    }
    fclose(fp);
    decrypt(info, index);
    printf("\n---END---\n");
    return EXIT_SUCCESS;
}

/* return 0 if not valid */
int isValidChar( int c ) {
    if (c < 0x20) {
        return 0;
    } else if ( c >= 0x20 && c < 0x30) {
    // 0x20 - 0x2f ! "" # $ % & ' () * +, -./
        return 1;
    } else if ( c >= 0x30 && c < 0x3A) {
    // 0x30 - 0x39 0-9
        return 1;
    } else if ( c >= 0x3A && c < 0x41) {
    // 0x3A - 0x40 : ; < = > ? @ 
        return 1;
    } else if ( c >= 0x41 && c < 0x5B) {
      // 0x41 - 0x5A A-Z
        return 1;
    } else if ( c >= 0x5B && c < 0x61) {
      // 0x5B - 0x60 [ \ ] ^ _ `
        return 0;
    } else if ( c >= 0x61 && c < 0x7B) {
      // 0x61 - 0x7A a-z
        return 1;
    } else if ( c >= 0x7B && c < 0x7F) {
      // 0x7B - 0x7E { | } ~
        return 0;
    }
    return 0;
}

int decrypt(char* info, int len) {
    char* result = malloc(sizeof(char)*len + 1);
    result[len-1] = '\0'; /* string */
    int d; /* key */
    char c; /* XO result*/
    char key[3];

    for ( int offset = 0; offset < 3; offset++) {
        for (d = 'a'; d <= 'z'; d++) {
            int i;
            for (i = offset; i < len; i+= 3){
                c = info[i] ^ d;  
                if (!isValidChar(c)) {
                    break; 
                }
            }
            if (i >= len) {
                // printf("\n\n key is  %c , i is %d, len is %d\n",  d, i, len);
                key[offset] = d;
                for (i = offset; i < len; ){
                    c = info[i] ^ d;
                    result[i] = c;
                    i+= 3;
                }
            }
        }
    } 
    result[len] = '\0'; /* string */
    printf("\n Total %d, key is %s \n%s\n\n", len, key,  result);  
    free(result);
    return 0;
}

/*

*/